17022
24070
在HTML中作为背景色输入时,某些随机字符串如何产生颜色?例如:
测试
...在所有浏览器和平台上产生背景为红色的文档。
有趣的是,虽然恰克诺里也产生红色背景,但恰克诺尔产生黄色背景。
这里发生了什么? 
这是Netscape时代的一大亮点:
丢失的数字被视为0 [...]。不正确的数字被简单地解释为0。例如,值#F0F0F0,F0F0F0,F0F0F,#FxFxFx和FxFxFx都相同。
它来自博客文章关于Microsoft Internet Explorer的颜色解析的一点怨言,其中涵盖了它的详细信息,包括不同长度的颜色值等。
如果我们从博客文章中依次应用规则,则会得到以下信息:
将所有无效的十六进制字符替换为0:
查克诺里斯变成c00c0000000
填充到下一个可被3(11→12)整除的字符总数:
c00c 0000 0000
分为三个相等的组,每个分量代表RGB颜色的相应颜色分量:
RGB(c00c,0000,0000)
将每个参数从右向下截断为两个字符。
最后,得出以下结果:
RGB(c0,00,00)=#C00000或RGB(192,0,0)
下面是一个示例,该示例演示了如何使用bgcolor属性来生成此“惊人的”颜色样本:
<表格>

查克·诺里斯
 T先生
 ninjaturtle 


生病
废话


这也回答了问题的另一部分:为什么bgcolor =“ chucknorr”产生黄色?好吧,如果我们应用规则,则字符串为:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192,192,0)]
呈浅金黄色。由于字符串以9个字符开头,因此我们这次保持第二个“ C”,因此最终以最终颜色值结束。
我最初是在有人指出您可以进行color =“ crap”时遇到此问题的,结果它变成棕色。
|
抱歉,我不同意,但是根据解析@Yuhong Bao发布的旧色值的规则,chucknorris不等于#CC0000,而是等于#C00000,红色非常相似,但略有不同。我使用Firefox ColorZilla加载项进行了验证。
规则规定:
通过添加0将字符串的长度设为3的倍数:chucknorris0
将字符串分成3个相等长度的字符串:chuc knor ris0
将每个字符串截断为2个字符:ch kn ri
保留十六进制值,并在必要时添加0:C0 00 00
我能够使用这些规则正确解释以下字符串:
幸运符
运气
运气好
今晚运气好
江南风格
更新:原来说颜色为#CC0000的原始答复者已经编辑了他们的答案以包括更正。
|
大多数浏览器将简单地忽略颜色字符串中的任何非十六进制值,而将非十六进制数字替换为零。
ChuCknorris转换为c00c0000000。此时,浏览器会将字符串分为三个相等的部分,分别指示红色,绿色和蓝色值:c00c 00000000。每个部分中的多余位都将被忽略,这将使最终结果#c00000为带红色。
请注意,这不适用于遵循CSS标准的CSS颜色解析。

偏红

与上述相同

黑色 | 原因是浏览器无法理解它,并尝试以某种方式将其转换为它可以理解的值,在这种情况下,将其转换为十六进制值! chucknorris以c开头,它是十六进制的可识别字符,它还将所有无法识别的字符转换为0! 因此,十六进制格式的chucknorris变为:c00c00000000,所有其他字符变为0,c保留在它们所在的位置... 现在它们被RGB(红色,绿色,蓝色)除以3 ... R:c00c,G:0000,B:0000 ... 但是我们知道RGB的有效十六进制只有2个字符,表示R:c0,G:00,B:00 因此,实际结果是: bgcolor =“#c00000”; 我还在图像中添加了步骤,为您提供了快速参考: | 浏览器试图将chucknorris转换为十六进制颜色代码,因为该值无效。 在chucknorris中,除c外的所有内容都不是有效的十六进制值。 因此将其转换为c00c00000000。 变成#c00000,红色阴影。 这似乎主要是与Internet Explorer和Opera(12)有关的问题,因为Chrome(31)和Firefox(26)都忽略了这一点。 附言括号中的数字是我测试过的浏览器版本。 轻一点 Chuck Norris不符合网络标准。 Web标准符合 给他。 #BADA55 | WHATWG HTML规范具有解析旧版颜色的确切算法值: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value。 用于解析颜色字符串的Netscape Classic代码是开源的: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155。 例如,请注意,每个字符都被解析为十六进制数字,然后在不检查溢出的情况下被转换为32位整数。 32位整数只能容纳8个十六进制数字,这就是为什么只考虑最后8个字符的原因。将十六进制数字解析为32位整数后,然后将它们除以16,直到它们适合8位,然后将其截断为8位整数,这就是为什么忽略前导零的原因。 更新:该代码与规范中定义的代码不完全匹配,但是唯一的区别是几行代码。我认为是添加了以下几行(在Netscape 4中): 如果(bytes_per_val> 4) { bytes_per_val = 4; } | 回答: 浏览器将尝试将chucknorris转换为十六进制值。 由于c是chucknorris中唯一有效的十六进制字符,因此该值变为:c00c00000000(对于所有无效的值均为0)。 然后,浏览器将结果分为3组:红色= c00c,绿色= 0000,蓝色= 0000。 由于html背景的有效十六进制值仅包含每种颜色类型(r,g,b)的2位数字,因此每组的最后2位数字均被截断,从而使rgb值c00000为砖红色调色调。 | chucknorris以c开头,浏览器将其读取为十六进制值。 因为A,B,C,D,E和F是十六进制字符。 浏览器将chucknorris转换为十六进制值C00C00000000。 然后将C00C00000000十六进制值转换为RGB格式(除以3): C00C00000000⇒R:C00C,G:0000,B:0000 浏览器仅需要两位数字来指示颜色: R:C00C,G:0000,B:0000⇒R:C0,G:00,B:00⇒C00000 最后,在网络浏览器中显示bgcolor = C00000。 这是一个演示它的示例: <表格> chucknorris c00c00000000 c00000 | 解析旧属性上的颜色的规则涉及到比现有答案中提到的步骤更多的步骤。将截断部分转换为两位数的部分描述为: 丢弃除最后8个字符以外的所有字符 只要所有组件都具有前导零,则一一丢弃前导零。 丢弃除前2个字符外的所有字符 一些例子: oooFoooFoooF 000F 000F 000F <-替换,填充和块 0F 0F 0F <-前导零被截断 0F 0F 0F <-从右截去2个字符 oooFooFFoFFF 000F 00FF 0FFF <-替换,填充和块 00F 0FF FFF <-前导零被截断 00 0F FF <-从右边截断为2个字符 ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <-替换,填充和块 BC000000 BC000000 BC000000 <-从左开始被截断为8个字符 BC BC BC <-从右截断为2个字符 AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <-替换,填充和块 0C000000 0C000000 0C000000 <-从左开始被截断为8个字符 C000000 C000000 C000000 <-前导零被截断 C0 C0 C0 <-从右截去2个字符 以下是该算法的部分实现。它不处理错误或用户输入有效颜色的情况。 函数parseColor(input){ // todo:如果输入为“”,则返回错误 输入= input.trim(); // todo:如果输入为“透明”,则返回错误 // todo:如果输入为命名颜色,则返回相应的#rrggbb // todo:如果输入匹配#rgb,则返回#rrggbb // todo:将大于U + FFFF的Unicode代码点替换为00 如果(input.length> 128){ 输入= input.slice(0,128); } 如果(input.charAt(0)===“#”){ 输入= input.slice(1); } 输入= input.replace(/ [^ 0-9A-Fa-f] / g,“ 0”); 而(input.length === 0 || input.length%3> 0){ 输入+ =“ 0”; } var r = input.slice(0,input.length / 3); var g = input.slice(input.length / 3,input.length * 2/3); var b = input.slice(input.length * 2/3); 如果(r.length> 8){ r = r.slice(-8); g = g.slice(-8); b = b.slice(-8); } while(r.length> 2 && r.charAt(0)===“ 0” && g.charAt(0)===“ 0” && b.charAt(0)===“ 0”){ r = r.slice(1); g = g.slice(1); b = b.slice(1); } 如果(r.length> 2){ r = r.slice(0,2); g = g.slice(0,2); b = b.slice(0,2); } 返回“#” + r.padStart(2,“ 0”)+ g.padStart(2,“ 0”)+ b.padStart(2,“ 0”); } $(function(){ $(“#input”)。on(“ change”,function(){ var input = $(this).val(); var color = parseColor(input); var $ cells = $(“#result tbody td”); $ cells.eq(0).attr(“ bgcolor”,输入); $ cells.eq(1).attr(“ bgcolor”,color); 变种值: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value。 用于解析颜色字符串的Netscape Classic代码是开源的: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155。 例如,请注意,每个字符都被解析为十六进制数字,然后在不检查溢出的情况下被转换为32位整数。 32位整数只能容纳8个十六进制数字,这就是为什么只考虑最后8个字符的原因。将十六进制数字解析为32位整数后,然后将它们除以16,直到它们适合8位,然后将其截断为8位整数,这就是为什么忽略前导零的原因。 更新:该代码与规范中定义的代码不完全匹配,但是唯一的区别是几行代码。我认为是添加了以下几行(在Netscape 4中): 如果(bytes_per_val> 4) { bytes_per_val = 4; } | 回答: 浏览器将尝试将chucknorris转换为十六进制值。 由于c是chucknorris中唯一有效的十六进制字符,因此该值变为:c00c00000000(对于所有无效的值均为0)。 然后,浏览器将结果分为3组:红色= c00c,绿色= 0000,蓝色= 0000。 由于html背景的有效十六进制值仅包含每种颜色类型(r,g,b)的2位数字,因此每组的最后2位数字均被截断,从而使rgb值c00000为砖红色调色调。 | chucknorris以c开头,浏览器将其读取为十六进制值。 因为A,B,C,D,E和F是十六进制字符。 浏览器将chucknorris转换为十六进制值C00C00000000。 然后将C00C00000000十六进制值转换为RGB格式(除以3): C00C00000000⇒R:C00C,G:0000,B:0000 浏览器仅需要两位数字来指示颜色: R:C00C,G:0000,B:0000⇒R:C0,G:00,B:00⇒C00000 最后,在网络浏览器中显示bgcolor = C00000。 这是一个演示它的示例: <表格> chucknorris c00c00000000 c00000 | 解析旧属性上的颜色的规则涉及到比现有答案中提到的步骤更多的步骤。将截断部分转换为两位数的部分描述为: 丢弃除最后8个字符以外的所有字符 只要所有组件都具有前导零,则一一丢弃前导零。 丢弃除前2个字符外的所有字符 一些例子: oooFoooFoooF 000F 000F 000F <-替换,填充和块 0F 0F 0F <-前导零被截断 0F 0F 0F <-从右截去2个字符 oooFooFFoFFF 000F 00FF 0FFF <-替换,填充和块 00F 0FF FFF <-前导零被截断 00 0F FF <-从右边截断为2个字符 ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <-替换,填充和块 BC000000 BC000000 BC000000 <-从左开始被截断为8个字符 BC BC BC <-从右截断为2个字符 AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <-替换,填充和块 0C000000 0C000000 0C000000 <-从左开始被截断为8个字符 C000000 C000000 C000000 <-前导零被截断 C0 C0 C0 <-从右截去2个字符 以下是该算法的部分实现。它不处理错误或用户输入有效颜色的情况。 函数parseColor(input){ // todo:如果输入为“”,则返回错误 输入= input.trim(); // todo:如果输入为“透明”,则返回错误 // todo:如果输入为命名颜色,则返回相应的#rrggbb // todo:如果输入匹配#rgb,则返回#rrggbb // todo:将大于U + FFFF的Unicode代码点替换为00 如果(input.length> 128){ 输入= input.slice(0,128); } 如果(input.charAt(0)===“#”){ 输入= input.slice(1); } 输入= input.replace(/ [^ 0-9A-Fa-f] / g,“ 0”); 而(input.length === 0 || input.length%3> 0){ 输入+ =“ 0”; } var r = input.slice(0,input.length / 3); var g = input.slice(input.length / 3,input.length * 2/3); var b = input.slice(input.length * 2/3); 如果(r.length> 8){ r = r.slice(-8); g = g.slice(-8); b = b.slice(-8); } while(r.length> 2 && r.charAt(0)===“ 0” && g.charAt(0)===“ 0” && b.charAt(0)===“ 0”){ r = r.slice(1); g = g.slice(1); b = b.slice(1); } 如果(r.length> 2){ r = r.slice(0,2); g = g.slice(0,2); b = b.slice(0,2); } 返回“#” + r.padStart(2,“ 0”)+ g.padStart(2,“ 0”)+ b.padStart(2,“ 0”); } $(function(){ $(“#input”)。on(“ change”,function(){ var input = $(this).val(); var color = parseColor(input); var $ cells = $(“#result tbody td”); $ cells.eq(0).attr(“ bgcolor”,输入); $ cells.eq(1).attr(“ bgcolor”,color); 变种